# vPresent is an immersive presentation creation and display application.
# Copyright (C) 2007-2009 by Priority 5 Holdings, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

import opendocument
od = opendocument
config_base = opendocument.bases.config

class BaseMixin(object):
   def getName(self):
      return self.config_name

   def hasChildren(self):
      return False

# XXX: Could this class be more Python-ic? It takes advantage of dynamic
# typing in the value property, but that's about it.
# XXX: Beware the order to deriving in order to get correct override from mixin.
class Item(BaseMixin, config_base.ConfigItem):
   '''
   Basic configuration item.  This pairs a name with a typed value.  The value
   property (accessible through the getValue() method) returns the value as
   its actual type and can be converted to a string representation by passing
   the value to str().
   '''
   __metaclass__ = od.OpenDocumentMeta
   childTypes=['PlainText',]
   def __init__(self, attrs):
      config_base.ConfigItem.__init__(self, attrs)

   def get_cdata(self):
      value = self.__getcdata().strip()

      if self.config_type == 'boolean':
         return opendocument.toBoolean(value)
      elif self.config_type == 'short' or self.config_type == 'int':
         return int(value)
      elif self.config_type == 'long':
         return long(value)
      elif self.config_type == 'double':
         return float(value)
      elif self.config_type == 'string':
         return value
      # TODO: Handle datetime and base64Binary more intelligently.
      elif self.config_type == 'datetime':
         return value
      elif self.config_type == 'base64Binary':
         return value

   def set_cdata(self, value):
      self.__setcdata(str(value))

class ContainerMixin(BaseMixin):
   __metaclass__ = od.MixinMeta
   childTypes = ['config:item', 'config:item-set', 'config:named-item-map', 'config:indexed-item-map']

class ItemSet(ContainerMixin, config_base.ConfigItemSet):
   __metaclass__ = od.OpenDocumentMeta
   def __init__(self, attrs):
      config_base.ConfigItemSet.__init__(self, attrs)

# NOTE: This class derives from Container because it is described in the
# OpenDocument specification as being a conianter "for all types of settings
# elements." Having it as a subclass of Container makes the algorithm for
# accessing settings a little simpler, too.
class ItemMapEntry(ContainerMixin, config_base.ConfigItemMapEntry):
   '''
   Provides a mapping between an item map's name and the entry.  A named entry
   in an item map contains one or more items (Item, ItemSet, NamedItemMap, or
   IndexedItemMap).  Given the nature of Python, these items are stored in the
   value property as a list, accessible using the getValue() method.
   '''
   def __init__(self, attrs):
      config_base.ConfigItemMapEntry.__init__(self, attrs)

class NamedItemMap(ContainerMixin, config_base.ConfigItemMapNamed):
   def __init__(self, attrs):
      config_base.ItemMapNamed.__init__(self, attrs)

   def getChildByName(self, name):
      for c in self._children:
         if c.getName() == name:
            return c

      return None

class IndexedItemMap(ContainerMixin, config_base.ConfigItemMapIndexed):
   __metaclass__ = od.OpenDocumentMeta
   childTypes=['config:item-map-entry',]
   def __init__(self, attrs):
      config_base.ConfigItemMapIndexed.__init__(self, attrs)
